package org.xiaov.extra.web;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.xiaov.config.autoconfigure.UploadOSSProperties;
import org.xiaov.execption.XiaovUtilsException;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * <p>
 * 文件上传
 * </p>
 *
 * @author xiaovcloud
 * @since 2021/5/19 17:22
 */
@Component
public class UploadHelper {
    private static final Logger log = LoggerFactory.getLogger(UploadHelper.class);
    /**
     * Endpoint 上传阿里云地址。
     */
    private static String endpoint;
    /**
     * 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维
     */
    private static String accessKeyId;
    /**
     * 账号的密码
     */
    private static String accessKeySecret;
    /**
     * 创建的bucket名
     */
    private static String bucketName;
    /**
     * 存放的文件夹
     */
    private static String fileHost;

    @Resource
    private UploadOSSProperties upload;

    @PostConstruct
    public void init() {
        UploadHelper.endpoint = upload.getEndpoint();
        UploadHelper.accessKeyId = upload.getAccessKeyId();
        UploadHelper.accessKeySecret = upload.getAccessKeySecret();
        UploadHelper.bucketName = upload.getBucketName();
        UploadHelper.fileHost = upload.getFileHost();
    }

    /**
     * 上传文件
     *
     * @param file       上传的文件
     * @param targetPath 上传的地址
     * @param isPrefix   前缀标志位
     * @return 文件名
     */
    @SuppressWarnings("ResultOfMethodCallIgnored")
    public static String upload(MultipartFile file, String targetPath, boolean isPrefix) {
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("文件未找到");
        }
        String fileName = getFileName(file, isPrefix);
        //创建对象文件目录
        File uploadDir = new File(targetPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdir();
        }
        File uploadFile = new File(uploadDir + File.separator + fileName);
        try {
            file.transferTo(uploadFile);
        } catch (IOException e) {
            log.error("上传文件失败", e);
            throw new RuntimeException("上传文件失败", e);
        }
        return fileName;
    }

    /**
     * 获取file生成新的文件名字
     *
     * @param file     上传服务器的文件
     * @param isPrefix 前缀标志位
     * @return 访问地址path
     */
    private static String getFileName(MultipartFile file, boolean isPrefix) {
        //获取文件名
        String originalFilename = file.getOriginalFilename();
        //获取文件前缀
        if (originalFilename == null) {
            throw new XiaovUtilsException("文件名不能为空！");
        }
        String prefix = originalFilename.substring(0, originalFilename.lastIndexOf("."));
        //获取文件后缀名
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        //使用uuid作为文件名防止重复
        String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        String fileName;
        if (isPrefix) {
            fileName = uuid + "_" + prefix + "." + suffix;
        } else {
            fileName = uuid + "." + suffix;
        }
        return fileName;
    }


    /**
     * 上传文件到oos
     *
     * @param file 上传的文件
     * @return 访问地址path
     */
    public static String uploadWithOss(MultipartFile file, boolean isPrefix) {
        //获取文件名
        String originalFilename = file.getOriginalFilename();
        //获取文件后缀名
        if (originalFilename == null) {
            throw new XiaovUtilsException("文件名不能为空！");
        }
        String substring = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        //使用uuid作为文件名防止重复,将字母变为小写
        String uuid = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        if (isPrefix) {
            //获取文件前缀
            String prefix = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            uuid = uuid + "_" + prefix;
        }
        String fileName = uuid + "." + substring;
        File tempFile = null;
        OSS ossClient = null;
        String fileUrl = "";
        try {
            tempFile = File.createTempFile(uuid, substring);
            //MultipartFile  转换为 File
            file.transferTo(tempFile);
            ClientBuilderConfiguration config = new ClientBuilderConfiguration();
            //开启允许Cname
            config.setSupportCname(true);
            // 创建OSSClient实例。
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, config);
            //创建文件路径
            fileUrl = fileHost + "/" + fileName;
            ossClient.putObject(new PutObjectRequest(bucketName, fileUrl, tempFile));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        } finally {
            //关闭
            assert ossClient != null;
            ossClient.shutdown();
            //删除临时生成的文件
            if (tempFile.exists()) {
                tempFile.deleteOnExit();
            }
        }
        return endpoint + "/" + fileUrl;
    }
}
